﻿using System;
using System.Collections.Generic;
using System.Text;

namespace eKanbanWPF.Model
{
    [Serializable]
    public class Task : IEnumerable<Member>
    {
        public delegate void TaskChagned(Task task);
        public event TaskChagned Changed;

        private List<Member> doers;

        public IList<Member> Doers { get { return doers.AsReadOnly(); } }
        
        public enum StatusType
        {
            Ongoing,
            Completed,
            Blocked,
            Defect
        }

        public Task(Feature feature)
        {
            doers = new List<Member>();
            finishTime = DateTime.MaxValue;
            startTime = DateTime.Now.Date;
            Feature = feature;
        }

        #region Properties
        string name;
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                if (Changed != null)
                {
                    Changed.Invoke(this);
                }
            }
        }

        Feature feature;
        public Feature Feature
        {
            get { return feature; }
            set
            {
                feature = value;
                if (Changed != null)
                {
                    Changed.Invoke(this);
                }
            }
        }
        string description;
        public string Description
        {
            get { return description; }
            set
            {
                description = value;
                if (Changed != null)
                {
                    Changed.Invoke(this);
                }
            }
        }
        int priority;
        public int Priority
        {
            get { return priority; }
            set
            {
                priority = value;
                if (Changed != null)
                {
                    Changed.Invoke(this);
                }
            }
        }
        private DateTime startTime;
        public DateTime StartTime
        {
            get { return startTime; }
            set
            {
                if (value > FinishTime)
                {
                    throw new ArgumentException("Start Time cannot be larger than Finish Time");
                };
                startTime = value;
                if (Changed != null)
                {
                    Changed.Invoke(this);
                }
            }
        }
        private DateTime finishTime;
        public DateTime FinishTime
        {
            get { return finishTime; }
            set
            {
                if (value < StartTime)
                {
                    throw new ArgumentException("Finish Time cannot be less than Start Time");
                }
                finishTime = value;
                if (Changed != null)
                {
                    Changed.Invoke(this);
                }
            }
        }
        DateTime deadline;
        public DateTime DeadLine
        {
            get { return deadline; }
            set
            {
                deadline = value;
                if (Changed != null)
                {
                    Changed.Invoke(this);
                }
            }
        }

        StatusType status;
        public StatusType Status
        {
            get { return status; }
            set
            {
                status = value;
                if (Changed != null)
                {
                    Changed.Invoke(this);
                }
            }
        }
        public bool Done { get { return Status == StatusType.Completed; } }
        public bool OnGoing { get { return Status == StatusType.Ongoing; } }
        #endregion

        #region GUI Properties
        public double Left { get; set; }
        public double Top { get; set; }
        public double Width { get; set; }
        public double Height { get; set; }
        #endregion

        public IEnumerator<Member> GetEnumerator()
        {
            return doers.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return doers.GetEnumerator();
        }

        public void AddNewMember(Member member) 
        {
            if (!doers.Contains(member))
            {                
                doers.Add(member);
                member.Take(this);
            }
        }

        public void RemoveMember(Member member)
        {
            if (doers.Contains(member))
            {
                member.CurTaskFinishTime = DateTime.Now.Date;
                doers.Remove(member);
                //set finish time of this task
                member.IsDoing = false;
            }
        }

        public override string ToString()
        {
            return Name;
            //string str = String.Format("Description: {0}\nPriority: {1}\tStatus: {2}\nStartTime: {3}\tFinishTime: {4}\tDeadline: {5}", Description, Priority, Status, StartTime, FinishTime, DeadLine);
            //str += "\nDoers:";
            //foreach (Member item in doers)
            //{
            //    str += String.Format("\n\tName: {0}", item.Name);
            //}
            //return str;
        }
    }
}
